#![allow(clippy::result_large_err)]

use anchor_lang::prelude::*;

declare_id!("cXszzoJqpg18G5i5AR2XfqS8zNExFB1Vs8bE3kHnE2o");

#[program]
pub mod votingdapp {
    use super::*;
 
    pub fn initialize_poll(ctx: Context<InitPoll>, poll_id: u64, description: String, poll_start: i64, poll_end: i64) ->Result<()>{
        let poll = &mut ctx.accounts.poll;
        poll.poll_id = poll_id;
        poll.description = description;
        poll.poll_start = poll_start;
        poll.poll_end = poll_end;
        poll.candidate_amount = 0;
        Ok(())
    }

   // 这个  _poll_id 没有直接使用， 但仍然是需要的， 保证正确 的生成pda 
    pub fn initialize_candidate(ctx: Context<InitCandidate>, candidate_name: String, _poll_id: u64) ->Result<()>{
        let candidate = &mut ctx.accounts.candidate;
        candidate.candidate_name = candidate_name;
        candidate.candidate_votes = 0;
        // 每 

        let poll = &mut ctx.accounts.poll;
        poll.candidate_amount +=1;

        Ok(())
    }

    pub fn vote(ctx: Context<Vote>,  candidate_name: String, _poll_id: u64) ->Result<()>{
        let candidate = &mut ctx.accounts.candidate;
        candidate.candidate_votes +=1;
       

        Ok(())
    }
 
}




#[account]
#[derive(InitSpace)]
pub struct Candidate {
    #[max_len(32)]
    pub candidate_name: String,

    pub candidate_votes: u64,
}


#[derive(Accounts)]
#[instruction[candidate_name:String,poll_id:u64]]
pub struct Vote<'info> {
    #[account(mut)]
    pub signer : Signer<'info>,

    #[account(
        mut,
        seeds = [poll_id.to_le_bytes().as_ref(), candidate_name.as_bytes()],
        bump,
       )]
    pub candidate: Account<'info,Candidate>,

    #[account(
        mut,
     seeds = [poll_id.to_le_bytes().as_ref()],
     bump,
    )]
    pub poll: Account<'info,Poll>,


    pub system_program: Program<'info,System>
}

#[derive(Accounts)]
#[instruction[candidate_name:String, poll_id:u64]]
pub struct InitCandidate<'info> {
    #[account(mut)]
    pub signer : Signer<'info>,

    #[account(
        mut,
     seeds = [poll_id.to_le_bytes().as_ref()],
     bump,
    )]
    pub poll: Account<'info,Poll>,

    #[account(
        init,
        seeds = [poll_id.to_le_bytes().as_ref(), candidate_name.as_bytes()],
        bump,
        payer = signer,
        space = 8+ Candidate::INIT_SPACE
       )]
    pub candidate: Account<'info,Candidate>,
    pub system_program: Program<'info,System>
}

#[account]
#[derive(InitSpace)]
pub struct Poll{
 pub poll_id:u64, 
 #[max_len(280)]
 pub description: String,
 pub poll_start: i64,
 pub poll_end: i64,
 pub candidate_amount: u64,  
}

#[derive(Accounts)]
#[instruction[poll_id:u64]]
pub struct InitPoll<'info> {
    #[account(mut)]
    pub signer : Signer<'info>,

    #[account(
     init,
     seeds = [poll_id.to_le_bytes().as_ref()],
     bump,
     payer = signer,
     space = 8+ Poll::INIT_SPACE
    )]
    pub poll: Account<'info,Poll>,
    pub system_program: Program<'info,System>
}


